package org.agiletestplus.client.ui;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.agiletestplus.client.objects.Configuration;
import org.agiletestplus.client.objects.ConfigurationType;
import org.damour.base.client.objects.PermissibleObject;
import org.damour.base.client.service.BaseServiceCache;
import org.damour.base.client.ui.buttons.Button;
import org.damour.base.client.ui.dialogs.IDialogCallback;
import org.damour.base.client.ui.dialogs.PromptDialogBox;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;

public class EditConfigurationTypePanel extends FlexTable {

  ConfigurationType type = null;
  TextBox nameTextBox = new TextBox();
  TextBox descriptionTextBox = new TextBox();
  ListBox configList = new ListBox();
  Button addConfigButton = new Button("Add");
  Button editConfigButton = new Button("Edit");
  Button removeConfigButton = new Button("Remove");
  final Set<PermissibleObject> toRemove = new HashSet<PermissibleObject>();
  PromptDialogBox configurationDialog = new PromptDialogBox("Manage Configuration", "OK", null, "Cancel", true, true);
  EditConfigurationPanel editConfigPanel = new EditConfigurationPanel();

  
  List<Configuration> configurationList = new ArrayList<Configuration>();
  
  public EditConfigurationTypePanel(ConfigurationType type) {
    this.type = type;
    populateUI();
  }
  
  public void applyConfigurations(List<Configuration> configurationList) {
    configList.clear();
    this.configurationList = configurationList;
    if (configurationList != null && configurationList.size() > 0) {
      for (final Configuration obj : configurationList) {
        configList.addItem(obj.getName());
      }
    }
  }
  
  public void fetchConfigurations() {
    if (type.getId() != null) {
      final AsyncCallback<List<PermissibleObject>> loadCallback = new AsyncCallback<List<PermissibleObject>>() {
        public void onFailure(Throwable caught) {
          Window.alert("Failure.");
        }
        @SuppressWarnings({ "unchecked", "rawtypes" })
        public void onSuccess(final List<PermissibleObject> configurationTypes) {
          applyConfigurations((List<Configuration>)(List)configurationTypes);
        };
      };
      BaseServiceCache.getService().getPermissibleObjects(type, "org.agiletestplus.client.objects.Configuration", loadCallback);
    }
  }
  
  public void populateUI() {
    configurationDialog.setContent(editConfigPanel);

    nameTextBox.setText(type.getName());
    descriptionTextBox.setText(type.getDescription());

    // TODO: manage a list of configuration objects
    
    // build ui
    int row = 0;
    setWidget(row, 0, new Label("Name"));
    setWidget(row, 1, nameTextBox);
    setWidget(++row, 0, new Label("Description"));
    setWidget(row, 1, descriptionTextBox);
    
    configList.setVisibleItemCount(10);
    configList.addItem("Loading...");
    configList.setWidth("200px");
    fetchConfigurations();
    
    setWidget(++row, 0, new Label("Configurations"));
    setWidget(row, 1, configList);
    
    HorizontalPanel configButtonPanel = new HorizontalPanel();

    configButtonPanel.add(addConfigButton);
    configButtonPanel.add(editConfigButton);
    configButtonPanel.add(removeConfigButton);
    setWidget(++row, 1, configButtonPanel);
    
    addConfigButton.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        editConfigPanel.apply(new Configuration());
        configurationDialog.center();
        configurationDialog.setCallback(new IDialogCallback() {
          @Override
          public void okPressed() {
            editConfigPanel.update();
            configurationList.add(editConfigPanel.configuration);
            applyConfigurations(configurationList);
          }
            
          @Override
          public void cancelPressed() {}
        });
      }
    });
    
    editConfigButton.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        if (getConfigList().getSelectedIndex() >= 0) {
          editConfigPanel.apply(configurationList.get(getConfigList().getSelectedIndex()));
          configurationDialog.center();
          configurationDialog.setCallback(new IDialogCallback() {
            @Override
            public void okPressed() {
              editConfigPanel.update();
              applyConfigurations(configurationList);
            }
              
            @Override
            public void cancelPressed() {}
          });
          applyConfigurations(configurationList);
        }
      }
    });
    
    removeConfigButton.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        // need to get index
        if (getConfigList().getSelectedIndex() >= 0) {
          PromptDialogBox dialog = new PromptDialogBox("Remove Configuration", "Yes", null, "No", true, true);
          dialog.setCallback(new IDialogCallback() {
            public void okPressed() {
              toRemove.add(configurationList.remove(getConfigList().getSelectedIndex()));
              applyConfigurations(configurationList);
            }
            public void cancelPressed() {
            }
          });
          dialog.setContent(new HTML("Are you sure you want to delete the configuration?"));
          dialog.center();
        }
      }
    });

  }
  
  public String getName() {
    return nameTextBox.getText();
  }
  
  public String getDescription() {
    return descriptionTextBox.getText();
  }
  
  public ListBox getConfigList() {
    return configList;
  }
}
